<script lang="ts">
export default {
  name: 'Study3StuDemo1'
}
</script>

<template>
  <h2>事件处理</h2>
  <div class="note">
    <p>1. v-on (简写为@)可用来监听DOM事件，并在触发时执行相应的JavaScript代码。</p>
    <dl>
      <dt>2. 事件处理值：</dt>
      <dd>
        ①内联事件处理器：事件被触发时执行的内联 JavaScript 语句 (与 onclick 类似) eg.foo() 和
        count++
      </dd>
      <dd>
        ②方法事件处理器：一个指向组件上定义的方法的属性名或是路径。eg.foo、foo.bar 和 foo['bar']
      </dd>
    </dl>
    <p>3. 事件修饰符：可以用于修改事件的默认行为，例如阻止事件冒泡或只在按下特定按键时触发事件。</p>
    <p>eg. .stop、.prevent、.capture、.self、.once、.passive</p>
    <p>4. 按键修饰符：可以用以监听特定按键的组合键，例如 @keyup.enter="submit"。</p>
    <p>
      eg.
      .enter、.tab、.delete、.esc、.space、.up、.down、.left、.right、.home、.end、.page-up、.page-down、.shift、.ctrl、.alt、.meta、.exact、.ctrl.alt、.ctrl.shift、.alt.shift、.ctrl.alt.shift
    </p>
    <p>5. 系统按键修饰符：可以用以监听系统按键，例如 @keyup.ctrl.a="selectAll"。</p>
    <p>eg. .ctrl、.alt、.shift、.meta、.ctrl.alt、.ctrl.shift、.alt.shift、.ctrl.alt.shift</p>
    <p>6. 鼠标按键修饰符：可以用以监听鼠标按键，例如 @click.left="doSomething"。</p>
    <p>eg. .left、.right、.middle、.aux1、.aux2、.aux3</p>
  </div>

  <hr class="hr-style" />
  <h3>内联事务处理器</h3>
  <div class="test">
    <p>count is: {{ count }}</p>
    <button type="button" @click="count++">add 1</button>
    <p style="color: salmon">
      可以在内联事件处理器中调用方法，这允许我们向方法传入自定义参数以代替原生事件
    </p>
    <button @click="say('hello')" style="margin-right: 10px">Say hello</button>
    <button @click="say('bye')">Say bye</button>
    <p style="color: salmon">可以在内联事件处理器中访问事件参数</p>
    <span>1. 使用特殊的 $event 变量 </span>
    <button @click="warn('Form cannot be submitted yet.', $event)">Submit</button><br />
    <span>2. 使用内联箭头函数 </span>
    <button @click="(event) => warn('Form cannot be submitted yet.', event)">Submit</button>
  </div>

  <hr class="hr-style" />
  <h3>方法事件处理器</h3>
  <div class="test">
    <button @click="greet">Greet</button>
  </div>

  <hr class="hr-style" />
  <h3>事件修饰符</h3>
  <div class="test">
    <!-- 单击事件将停止传递 -->
    <a @click.stop="greet"></a>
    <!-- 提交事件将不再重新加载页面 -->
    <form @submit.prevent="onSubmit"></form>
    <!-- 修饰语可以使用链式书写 -->
    <a @click.stop.prevent="greet"></a>
    <!-- 也可以只有修饰符 -->
    <form @submit.prevent></form>
    <!-- 仅当 event.target 是元素本身时才会触发事件处理器 -->
    <!-- 例如：事件处理器不来自子元素 -->
    <div @click.self="greet">...</div>
    <p style="color: pink">
      注：@click.prevent.self 会阻止元素及其子元素的所有点击事件的默认行为，而 @click.self.prevent
      则只会阻止对元素本身的点击事件的默认行为。
    </p>
    <!-- 添加事件监听器时，使用 `capture` 捕获模式 -->
    <!-- 例如：指向内部元素的事件，在被内部元素处理前，先被外部处理 -->
    <div @click.capture="greet">...</div>

    <!-- 点击事件最多被触发一次 -->
    <a @click.once="greet"></a>

    <!-- 滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成 -->
    <!-- 以防其中包含 `event.preventDefault()` -->
    <div @scroll.passive="onScroll">...</div>
    <p style="color: pink">
      请勿同时使用 .passive 和 .prevent，因为 .passive
      已经向浏览器表明了你不想阻止事件的默认行为。如果你这么做了，则 .prevent
      会被忽略，并且浏览器会抛出警告。
    </p>
  </div>

  <hr class="hr-style" />
  <h3>按键修饰符</h3>
  <div class="test">
    <!-- 仅在 `key` 为 `Enter` 时调用 `submit` -->
    <!-- <input @keyup.enter="submit" />
    <input @keyup.page-down="onPageDown" /> -->
  </div>

  <hr class="hr-style" />
  <h3>系统按键修饰符</h3>
  <div class="test">
    <!-- Alt + Enter -->
    <!-- <input @keyup.alt.enter="clear" /> -->
     <!-- Ctrl + 点击  -->
    <!-- <div @click.ctrl="doSomething">Do something</div> -->
    <!-- 当按下 Ctrl 时，即使同时按下 Alt 或 Shift 也会触发 -->
    <!-- <button @click.ctrl="onClick">A</button> -->
    <!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
    <!-- <button @click.ctrl.exact="onCtrlClick">A</button> -->
    <!-- 仅当没有按下任何系统按键时触发 -->
    <!-- <button @click.exact="onClick">A</button>  -->
  </div>

  <hr class="hr-style" />
  <h3>鼠标按键修饰符</h3>
  <div class="test"></div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

// 数据
const count = ref(0)

const name = ref('Vue.js')

// 方法
function greet(event: Event) {
  alert(`Hello, ${name.value}!`)
  // event 是 DOM 原生事件
  if (event) {
    alert((event.target as Element).tagName)
  }
}

function say(message: string) {
  alert(message)
}

function warn(message: string, event: Event) {
  if (event) {
    event.preventDefault()
  }
  alert(message)
}

function onSubmit(event: Event) {
  console.log('Form submitted.')
}

function onScroll(event: Event) {
  console.log('Scrolling:', event)
}
</script>

<style scoped>
body {
  padding: 20px;
}
h2 {
  color: red;
}
h3 {
  color: rgb(220, 85, 85);
}
h4 {
  color: skyblue;
}
.hr-style {
  border: 3px solid gold;
  margin: 20px 0;
}
.note {
  margin: 10px;
  padding: 10px;
  border: 3px solid rgb(221, 121, 202);
}
.note {
  color: rgb(226, 106, 204);
  font-weight: bold;
}
</style>
